package cn.melonlib.aap.user.comp.service;

import cn.melonlib.aap.user.model.entity.Account;
import cn.melonlib.aap.user.model.entity.AccountPassword;
import cn.melonlib.aap.user.model.entity.AccountPasswordRecord;
import cn.melonlib.aap.user.model.entity.User;
import cn.melonlib.aap.user.model.enums.PasswordStrength;
import cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService;
import cn.melonlib.cores.jpa.comp.Dao;
import cn.melonlib.cores.jpa.model.bean.impl.DefaultQuery;
import cn.melonlib.cores.model.anno.*;
import cn.melonlib.security.encryption.anno.Decrypt;
import cn.melonlib.security.encryption.anno.Encrypt;
import cn.melonlib.security.encryption.anno.SecurityService;
import cn.melonlib.security.encryption.enums.EncTarget;
import org.intellij.lang.annotations.Language;
import org.springframework.beans.BeanUtils;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.List;

import static cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService.ROOT_METHOD.*;
import static cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService.ROOT_METHOD.LOAD_ALL;

@Service
@WorkerComment("账户管理")
@WorkerService(
     module = "account"
    ,model = @WorkerModel(
            modelType = Account.class
    )
        ,ignores = {SAVE,REMOVE_BY_ID,REMOVE_BY_ID_LIST,LIST,TOTAL_COUNT,GET_BY_ID,LOAD_ALL}
)
@SecurityService
public class AccountManagerService extends WorkerBasicService<Account> {

//    @Decrypt(target = EncTarget.STORE)
//    public User encVal(@Encrypt(target = EncTarget.STORE,paths = {"code","realName"}) User val){
//        System.out.println(val.getNickName());
//        System.out.println(val.getCode());
//        System.out.println(val.getRealName());
//        return val;
//    }

//    @WorkerStore
//    @WorkerComment("创建账户")
    @Transactional(value = Transactional.TxType.REQUIRED,rollbackOn = Exception.class)
    public Account createAccount(
            @WorkerParameter(value = "account",comment = "账号信息",required = true) Account account,
            @WorkerParameter(value = "password",comment = "密码",required = true)@Encrypt(target = EncTarget.STORE) String password
                                 ){
        @Language("HQL") String hql="from Account where account=?1 and tenantId=?2";
        List<Account> accounts=dao.<List<Account>,DefaultQuery>search(new DefaultQuery(hql,List.of(account.getAccount(),account.getTenantId()))).getResult();
        Assert.isTrue(accounts.isEmpty(),"账户已被占用");
        Account result=dao.save(account).getResult();
        dao.flush();
        this.modifyPassword(result,password);
        return result;
    }


    @WorkerStore
    @WorkerComment("修改密码")
    @Transactional(value = Transactional.TxType.REQUIRED,rollbackOn = Exception.class)
    public Boolean modifyPassword(
            @WorkerParameter(value = "account",comment = "登陆账户名",required = true) String account,
            @WorkerParameter(value = "tenant",comment = "租户名",required = true) String tenant,
            @WorkerParameter(value = "password" ,comment = "新密码",required = true) String password){
        @Language("HQL") String hql="from Account where account=?1 and tenantId=?2";
        List<Account> accounts=dao.<List<Account>,DefaultQuery>search(new DefaultQuery(hql,List.of(account,tenant))).getResult();
        Assert.isTrue(accounts.size()>0,"未找到账户");
        this.modifyPassword(accounts.get(0),password);
        return true;
    }

    @Transactional(value = Transactional.TxType.REQUIRED,rollbackOn = Exception.class)
    public Boolean modifyPassword(Account account,@Encrypt(target = EncTarget.STORE) String password){
        @Language("HQL") String passwordhql="delete from AccountPassword where account=?1";
        dao.updateQl(passwordhql,List.of(account));
        @Language("HQL") String pwdRecord="update AccountPasswordRecord set scrap=true,scrapDateTime=?1 where account=?2 and scrap=false";
        dao.updateQl(pwdRecord,List.of(System.currentTimeMillis(),account));
        AccountPassword accountPassword=new AccountPassword();
        accountPassword.setAccount(account);
        accountPassword.setPassword(password);
        accountPassword.setScore(0);
        accountPassword.setStrength(PasswordStrength.MEDIUM);
        accountPassword=dao.save(accountPassword).getResult();
        AccountPasswordRecord accountPasswordRecord=new AccountPasswordRecord();
        BeanUtils.copyProperties(accountPassword,accountPasswordRecord,"id");
        dao.save(accountPasswordRecord);
        return true;
    }
}
